package com.gitee.cliveyuan.tools.data;

import com.gitee.cliveyuan.tools.Assert;
import com.gitee.cliveyuan.tools.exception.ExcelException;
import com.google.common.collect.Lists;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by Clive on 2019/10/28.
 */
@Data
@Builder
@Slf4j
public class ExcelReader implements Serializable {

    private String excelPath;
    @Builder.Default
    private List<SheetInfo> sheetInfoList = Lists.newArrayList();
    @Builder.Default
    private int skipRowNo = 1;

    public ExcelReader addSheetInfo(String sheetName, Class clazz) {
        sheetInfoList.add(new SheetInfo(sheetName, clazz));
        return this;
    }

    @Data
    public class SheetInfo implements Serializable {
        private String sheetName;
        private Class clazz;

        public SheetInfo(String sheetName, Class clazz) {
            this.sheetName = sheetName;
            this.clazz = clazz;
        }
    }

    @Data
    public class SheetData<T> implements Serializable {
        private String sheetName;
        private List<T> dataList;

        public SheetData(String sheetName, List<T> dataList) {
            this.sheetName = sheetName;
            this.dataList = dataList;
        }
    }

    public List<SheetData> read() {
        List<SheetData> resultList = Lists.newArrayList();
        Assert.notEmpty(sheetInfoList, "sheetInfoList can't be empty");
        String[] sheetNames = sheetInfoList.stream().map(SheetInfo::getSheetName).toArray(String[]::new);
        Map<String, SheetInfo> sheetInfoMap = sheetInfoList.stream().collect(Collectors.toMap(SheetInfo::getSheetName, Function.identity()));
        Map<String, List<String[]>> sheetDataMap = ExcelTools.readExcel(excelPath, sheetNames);
        sheetDataMap.forEach((sheetName, dataArray) -> {
                    SheetInfo sheetInfo = sheetInfoMap.get(sheetName);
                    if (Objects.isNull(sheetInfo)) {
                        log.warn("can't find sheetInfo of sheetName " + sheetName);
                        throw ExcelException.dataConvertError();
                    }
                    resultList.add(new SheetData(sheetName, TableUtils.dataToObject(skipRowNo, dataArray, sheetInfo.getClazz())));
                }
        );
        return resultList;
    }
}
